package com.lx.security.demo.config;

import com.lx.security.demo.filter.JwtAuthenticationTokenFilter;
import com.lx.security.demo.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author lX
 * @version JDK 8
 * @className SecurityConfig (此处以class为例)
 * @date 2024/12/4
 * @description TODO
 */
@Configuration
@EnableWebSecurity //开启spring sercurity支持
@EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = true,
        prePostEnabled = true)
public class SecurityConfig {

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;
    @Autowired
    private LoginFailureHandler loginFailureHandler;
    @Autowired
    private LoginAuthenticationEntryPoint loginAuthenticationEntryPoint;

    @Autowired
    private BusinessAccessDeniedHandler bussinessAccessDeniedHandler;

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Autowired
    private CustomLogoutSuccessHandler myLogoutSuccessHandler;


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        //对请求进行访问控制设置
        http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests
                //设置哪些路径可以直接访问，不需要认证
                .requestMatchers("/user/**").hasRole("admin")
                //.requestMatchers("/index").permitAll()
                .anyRequest().authenticated() //其他路径的请求都需要认证
        );

        //自定义登录逻辑
        http.formLogin((formLogin) -> formLogin
                .loginProcessingUrl("/login")//登录访问路径：前台界面提交表单之后跳转到这个路径进行UserDetailsService的验证，必须和表单提交接口一样
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
        );

        //添加JWT登录拦截器，在登录之前获取token并校验
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);


        //访问受限后的异常处理
        http.exceptionHandling((exceptionHandling) -> exceptionHandling
                .authenticationEntryPoint(loginAuthenticationEntryPoint)
                .accessDeniedHandler(bussinessAccessDeniedHandler)
        );
        //自定义退出登录逻辑
        http.logout((logout) -> logout
                .logoutSuccessHandler(myLogoutSuccessHandler)
        );
        //关闭跨站点请求伪造csrf防护
        http.csrf((csrf) -> csrf.disable());



        return http.build();
    }

    //配置权限
//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
//
//        //前后端分离认证逻辑
//        http.formLogin((formLogin) -> formLogin
//                .loginProcessingUrl("/login") //登录访问接口
//                .successHandler(new LoginSuccessHandler()) //登录成功处理逻辑
//                .failureHandler(new LoginFailureHandler()) //登录失败处理逻辑
//        );
//
//        //认证访问控制
////        http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests
////                .requestMatchers("/login").permitAll() //放行登录界面
////                .requestMatchers("/index").hasRole("admin")//有admin角色才可以访问
////                .requestMatchers("/index2").hasRole("user")//有user角色才可以访问
////                .requestMatchers("/user/*").hasAnyAuthority("user:api")//有user:api权限才可以访问
////                .requestMatchers("/order/*").hasAnyAuthority("order.api")//有order.api权限才可以访问
////                .anyRequest().authenticated()
////        );
//        //权限不通过异常处理
//        http.exceptionHandling((exceptionHandling)->{
//            exceptionHandling.accessDeniedHandler(new BusinessAccessDeniedHandler());
//        });
//        return http.build();
//
//
//    }
//
//    @Bean
//    public UserDetailsService userDetailsService() {
//
//        UserDetails admin =  User.withDefaultPasswordEncoder()
//                .username("admin")
//                .password("123456")
//                .roles("admin")
//                .build();
//
//
//        UserDetails user =  User.withDefaultPasswordEncoder()
//                .username("user")
//                .password("123456")
//                .authorities("user")
//                .build();
//        return new InMemoryUserDetailsManager(user,admin);
//    }

     //前后端分离配置
//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//
//        //表单提交
//        http.formLogin((formLogin)->{
//            formLogin.loginProcessingUrl("/login")
//                    .successHandler(new LoginSuccessHandler())
//                    .failureHandler(new LoginFailureHandler());
//        });
//        return http.build();
//    };


    //自定义配置登录界面配置
//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
//
//        //表单提交
//        http.formLogin((formLogin)->{
//            formLogin.loginPage("/login.html")
//                    .loginProcessingUrl("/user/login")
//                    .defaultSuccessUrl("/admin/demo");
//        });
//        //对请求进行访问控制设置
//        http.authorizeHttpRequests((authorizeHttpRequests)->{
//            authorizeHttpRequests
//                    //放行路径
//                    .requestMatchers("/login.html","user/login").permitAll()
//                    //其他需要认证的路径
//                    .anyRequest().authenticated();
//
//        });
//
//        //关闭跨站点请求伪造csrf防护
//        http.csrf((csrf) -> csrf.disable());
//
//        return http.build();
//
//    }

    /**
     * 配置用户信息
     * @return
     */
//    @Bean
//    public UserDetailsService userDetailsService(){
//
////        UserDetails user1 = User.withDefaultPasswordEncoder()
////                .username("luoxue")
////                .password("123456")
////                .build();
////
////        return new InMemoryUserDetailsManager(user1);
//                //$2a$10$rOwcbxRvDMuI9d0oHFn3Qu2TnSh.kyOis4Q7AeCZ8xdQ75sSRSWpi
//                UserDetails user = User
//                .withUsername("luoxue")
//                .password(passwordEncoder().encode("123456"))
//                .build();
//                return new InMemoryUserDetailsManager(user);
//
//
//    }

//    @Bean
//    public PasswordEncoder passwordEncoder(){
//        return new BCryptPasswordEncoder();  //加密方式bcrypt
//    }
}
